package com.youku.component;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.youku.component.procedure.Procedure;
import com.youku.component.report.ReportHolder;
import com.youku.component.report.TestRecord;
import com.youku.component.variable.LocalDefVariable;
import com.youku.exception.AssertException;
import com.youku.expression.Position;
import com.youku.expression.environment.EnvironmentFactory;

/**
 * 测试用例
 * 
 * @author loda
 *
 */
public class TestCase extends BaseAttribute implements SuiteStep {

	private static final Logger logger = LoggerFactory.getLogger(TestCase.class);

	protected Project project;

	private TestSuite suite;

	public TestCase() {
	}

	public TestCase(TestSuite suite) {
		this.suite = suite;
		this.project = suite.getProject();
	}

	public TestSuite getSuite() {
		return suite;
	}

	public void setSuite(TestSuite suite) {
		this.suite = suite;
	}

	public Project getProject() {
		return project;
	}

	@Override
	public void run() {
		logger.info("===================testcase==================>开始执行测试用例{}", id);
		logger.debug("现在的变量环境为：\n{}", EnvironmentFactory.environmentToString());
		logger.info("<===================testcase==================测试用例{}测试完成", id);
		// 测试用例通过，将状态改为通过
		try {
			super.run();
			ReportHolder.addRecordForReport(TestRecord.createSuccessRecord(this));
		} catch (AssertException e) {
			logger.debug("-----------------------------------------------------\n失败了，获取到原因为:" + e.getMessage());
			// 测试用例不通过，将状态改为不通过
			ReportHolder.addRecordForReport(TestRecord.createFailRecord(this, e.getMessage()));
		}
	}

	public Procedure getProcedure(String procedureId) {
		return (Procedure) getStepWithKey(procedureId);
	}

	@Override
	public void addVariable(String key, Object value) {
		EnvironmentFactory.buildLocal(getProjectId(), id, key, value);
	}

	@Override
	public String getProjectId() {
		return project.getId();
	}

	@Override
	public String getCaseId() {
		return id;
	}

	@Override
	public String getSuiteId() {
		return suite.getId();
	}

	/**
	 * 引用模板，将模板中的执行步骤step全部移至测试用例中，同时将传递的参数替换过去
	 * 
	 * @param template
	 * @param params
	 */
	public void refTemplate(Template template, Map<String, String> params) {
		for (Step s : template.getStepList()) {
			if (s instanceof CaseStep) {
				CaseStep step = ((CaseStep) s).cloneStep();
				step.updatePosition(Position.create(this));
				step.setScope(this);

				if (step instanceof LocalDefVariable) {
					// 查看是否定义了变量，如果定义了，就将准备的参数传递过去进行参数设值
					LocalDefVariable pdv = (LocalDefVariable) step;
					String newValue = params.remove(pdv.getName());
					if (newValue != null) {
						pdv.setExpression(newValue);
						step = pdv;
					}
				}

				s = step;
			}

			addStep(s.getKey(), s);
		}
	}

	@Override
	public String getKey() {
		return id;
	}
}
